package cn.com.pc.content.service.es;

import cn.com.pc.content.dto.PageResult;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestionBuilder;
import org.elasticsearch.search.suggest.completion.FuzzyOptions;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public interface ESQueryService {

    /**
     * 查询
     **/
    SearchResponse search(SearchRequest request);
    /**
     * 查询
     **/
    <T> List<T> search(SearchSourceBuilder builder, Class<T> c, String... idxNames);

    /**
     * 查询
     **/
    SearchHit[] search(SearchSourceBuilder builder, String... idxNames);

    /**
     * 查询
     **/
    <T> PageResult<T> search(SearchSourceBuilder builder, Class<T> c, int pageNo, int pageSize, String... idxNames);
    /**
     * 查询
     **/
    PageResult<Object> search(SearchSourceBuilder builder, int pageNo, int pageSize, String... idxNames);

    /**
     * 大数据量查询，利用scroll分页
     */
    SearchResponse searchScrollResponse(SearchScrollRequest scrollRequest);

    /**
     * 大数据量查询，利用scroll分页
     * */
    List<ElasticEntity> searchScroll(SearchSourceBuilder builder, String... idxNames);

    /**
     * 大数据量查询，利用scroll_after分页
     * */
    List<ElasticEntity> searchScrollAfter(SearchSourceBuilder builder, String... idxNames);

    /**
     * 建议
     *
     * @param builder 建议参数配置
     * @param idxNames       索引名称
     */
    <T> List<T> suggest(SearchSourceBuilder builder, Class<T> c, String... idxNames);

    /**
     * 建议
     *
     * @param builder 建议参数配置
     * @param idxNames       索引名称
     */
    Suggest suggest(SearchSourceBuilder builder, String... idxNames);

    /**
     * 建议
     *
     * @param suggestBuilder 指定在哪个字段搜索以及输入文本等参数配置
     * @param suggestionName 建议名称
     * @param idxNames       索引名称
     */
    <T> List<T> suggest(SuggestionBuilder<?> suggestBuilder, String suggestionName, Class<T> c, String... idxNames);

    /**
     * 词条建议器
     *
     * @param suggestField    建议字段
     * @param suggestMaxCount 返回建议数据大小
     * @param query           输入
     * @param indexNames      索引名称
     **/
    <T> List<T> termSuggest(String suggestField, String query, Integer suggestMaxCount, Class<T> c, String... indexNames);

    /**
     * 词组建议器
     *
     * @param suggestField    建议字段
     * @param suggestMaxCount 返回建议数据大小
     * @param query           输入
     * @param indexNames      索引名称
     **/
    <T> List<T> phraseSuggest(String suggestField, String query, Integer suggestMaxCount, Class<T> c, String... indexNames);

    /**
     * 自动完成建议器
     *
     * @param suggestField    建议字段
     * @param suggestMaxCount 返回建议数据大小
     * @param query           输入
     * @param indexNames      索引名称
     **/
    <T> List<T> completionSuggest(String suggestField, String query, Integer suggestMaxCount, Class<T> c, String... indexNames);

    /**
     * 模糊选项
     *
     * @param fuzzyMinLength
     * @param fuzzyPrefixLength
     */
    FuzzyOptions getFuzzyOptions(int fuzzyMinLength, int fuzzyPrefixLength);

    /**
     * 解析建议结果成实体集合
     * @param suggestions 建议结果
     * @param suggestName 建议名称
     * @param c 实体类型
     * */
    <T> List<T> getSuggestResults(Suggest suggestions, String suggestName, Class<T> c);

    /**
     * 多索引搜索
     * @param searchRequestMap 请求参数集合，key为索引名称，value为SearchSourceBuilder
     * @return
     */
    Map<String, Object> multiSearch(Map<String, SearchSourceBuilder> searchRequestMap);

    /**
     * 清除滚屏
     */
    void clearScroll(String scrollId) throws IOException;
}
